Skip to content

ci: key E2E workflow_dispatch concurrency on head_sha - #1367

Merged
chaojhou merged 2 commits into
mainfrom
ci/e2e-dispatch-concurrency-head-sha
Sep 4, 2026
Merged

ci: key E2E workflow_dispatch concurrency on head_sha#1367
chaojhou merged 2 commits into
mainfrom
ci/e2e-dispatch-concurrency-head-sha

Conversation

@jiagaoxiang

Copy link
Copy Markdown
Collaborator

Summary

workflow_dispatch has no pull_request.number / issue.number, so CI E2E concurrency fell through to github.ref (refs/heads/main for every dispatch). cancel-in-progress: true then killed the previous GPU smoke — #1325's dispatch cancelled #1322's run 33463143636 after ~58 min on the GPU.

This keys the group on inputs.head_sha (then inputs.head_ref) before github.ref, so two fork-PR dispatches can coexist. Same idea on Forge E2E job concurrency (head_sha before head_ref).

forge-kernel-bench.yml already uses a single forge-kernel-bench group with cancel-in-progress: false, so dispatches serialize instead of killing each other. Left it alone.

Test plan

  • Dispatch CI E2E for two different head_shas from main and confirm the first run is not cancelled
  • PR / /retest / retest label path still cancels the same-PR in-flight run

Fork PRs only get secrets via workflow_dispatch. That event has no
pull_request.number, so the group fell through to refs/heads/main and
cancel-in-progress killed the previous GPU smoke (#1322 cancelled by #1325).
@jiagaoxiang
jiagaoxiang requested a review from a team as a code owner September 1, 2026 15:40
@jiagaoxiang jiagaoxiang added the skip-e2e-test It's a PR that doesn't need to be e2e tested label Sep 1, 2026
@jiagaoxiang
jiagaoxiang enabled auto-merge (squash) September 1, 2026 15:40
The Forge gate counted the old group string (0==2 after the workflow
change). CI E2E's guard only required github.ref, which is how two
dispatches shared refs/heads/main and cancelled each other.

@zoroyihan7 zoroyihan7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — approving. This is the fix for a bug that was actively burning GPU hours, and the diagnosis and the key are both right.

For context on why this matters: I hit this twice from both sides. A dispatch I made for #1322 ran ~58 minutes and was cancelled 18 seconds after a dispatch for #1325 was created; later my dispatch for #1322 killed one of yours that had been queued for 2h51m. Every workflow_dispatch collapsed to ci-e2e-refs/heads/main, and since dispatch is the only way to get a real e2e on a fork PR (no secrets on pull_request), two fork PRs could never both be validated — and the loser vanished silently.

What I verified

  • inputs.head_sha is safe on non-dispatch events. This was my main worry, since the workflow-level concurrency expression is evaluated before any job's if, so a bad reference would break run creation for every event. Empirically fine: the pull_request-triggered CI E2E and Forge E2E runs on this very branch both completed successfully with the new expression.
  • resolve really does export head_sha in both workflows, so the forge-e2e side isn't silently falling through to head_ref.
  • The keys behave correctly at the boundaries. Two dispatches for different SHAs land in different groups (the fix); two for the same SHA still supersede each other (desirable). The noop-comment guard is untouched and still first in the chain.
  • Merged main locally — this branch is 121 commits behind and #1376 touched both forge-e2e.yml and test_forge_e2e_gate.py. Merges clean, fix intact, 15 passed, and scripts/tests/ plus the guard file are 195 passed.
  • Mutation-tested it. Reverting the ci-e2e group, reverting both forge-e2e groups, and moving head_sha after github.ref each turn a test red. So the tests genuinely pin the change rather than just describing it.

One hole, non-blocking

Deleting head_sha: ${{ steps.decide.outputs.head_sha }} from resolve.outputs in forge-e2e.yml leaves all 15 tests green. The group expression then silently falls through to head_ref, and the bug is back with CI still passing — which is the same silent-fallthrough shape this PR exists to fix. The tests string-match the consumer (the group expression) but never assert the producer it depends on.

One line in test_forge_e2e_gate.py closes it:

assert "head_sha: ${{ steps.decide.outputs.head_sha }}" in workflow

Worth adding, but I don't want to hold up a fix that's costing real GPU time. Take it here or as a follow-up.

@chaojhou
chaojhou disabled auto-merge September 4, 2026 10:21
@chaojhou
chaojhou merged commit b748284 into main Sep 4, 2026
33 checks passed
@chaojhou
chaojhou deleted the ci/e2e-dispatch-concurrency-head-sha branch September 4, 2026 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-e2e-test It's a PR that doesn't need to be e2e tested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants